package com.sann.util;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;

/**
 * 用于记录日志的工具类，它里面提供了公共的代码
 */
@Slf4j
public class Logger {

    /**
     * 环绕通知
     * 问题：
     *      当我们配置了环绕通知之后，切入点方法并没有执行，而环绕通知方法执行了。
     * 分析：
     *      通过对比动态代理中环绕通知代码（ invoke(proxy,method,args)方法就是环绕通知 ）,发现动态代理的
     *      环绕通知有明确的切入点方法（ method.invoke(target,args) ）调用,而我们这里的代码中没有
     * 解决：
     *      Spring框架为我们提供了一个接口，ProceedingJoinPoint。该接口有一个方法proceed()，此方法就相当于明确调用
     *      切入点方法。该接口可以作为环绕通知的方法参数，在程序执行时，spring会为我们提供该接口的实现类供我们使用。
     *
     * spring中的环绕通知：
     *      它是spring框架为我们提供的一种可以在代码中手动控制增强方法何时执行的方式。（除了xml配置和注解，还可以代码控制）
     */
    public Object aroundPrintLog(ProceedingJoinPoint pjp){
        Object rtValue = null;
        try {
            Object[] args = pjp.getArgs();//拦截到的方法入参
            log.info("前置通知...");
            rtValue = pjp.proceed(args);//调用目标方法，并返回目标方法返回值
            log.info("后置通知...");
            return rtValue;
        }catch (Throwable t){
            log.info("异常通知...");
            throw new RuntimeException(t);
        }finally {
            log.info("最终通知...");
        }
    }

}























